/*
 * @Author: yoola youlikesoilove@qq.com
 * @Date: 2024-12-08 21:48:59
 * @LastEditors: yoola youlikesoilove@qq.com
 * @LastEditTime: 2024-12-24 23:50:08
 * @FilePath: \CrabSystemProject\src\ModuleCenter\ConfigManager.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置:
 * https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "ConfigManager.hpp"
#include <iostream>
#include <fstream>

using namespace std;

// 默认配置（静态变量）
const nlohmann::ordered_json defaultConfig = {
    {"appName", "crab-system"},
    {"version", "1.0.0"},
    {"debug", false},
    {"deviceLists",
     {{"temperature-reader",
       {{"isopen", true},
        {"auto-cooling",
         {{"control_mode", "auto-control"},
          {"auto-control",
           {{"bind_controller_func_index", "Y1"},
            {"open_to_output_state", true},
            {"temperature-Threshold-open", 40.0},
            {"temperature-Threshold-close", 30.0},
            {"description",
             "当检测到温度高于'temperature-Threshold-open'时,向'bind_controller_func_index'"
             "输出'open_to_output_state'极性，低于'temperature-Threshold-close'"
             "关闭输出，降温期间保持输出极性。"}}},
          {"keep-close",
           {{"bind_controller_func_index", "Y1"},
            {"open_to_output_state", false},
            {"description", "'bind_controller_func_index'保持输出'open_to_output_state'"}}},
          {"keep-open",
           {{"bind_controller_func_index", "Y1"},
            {"open_to_output_state", true},
            {"description", "'bind_controller_func_index'保持输出'open_to_output_state'"}}}}}}},
      {"IO-controller",
       {{"isopen", true},
        {"func_index",
         {{"Y1", {{"isopen", true}, {"dev_name", "auto-cooling"}}},
          {"Y2", {{"isopen", false}, {"dev_name", "no-use"}}},
          {"Y3", {{"isopen", false}, {"dev_name", "no-use"}}},
          {"Y4", {{"isopen", true}, {"dev_name", "no-use"}}}}}}},
      {"weight-reader",
       {{"isopen", true},
        {"record_real_weight_data", {{"isopen", false}, {"freq_ms", 500}}},
        {"auto_take_pic",
         {{"isopen", true},
          {"control_mode", "add-with-pic"},
          {"add-with-pic",
           {{"min-add-step-weight", 50},
            {"permitted-data-fluctuations", 10},
            {"over-permit-wait-period", 50},
            {"description",
             "当检测到'min-add-step-weight'的重量增加时，进行拍照，允许的数据波动为'permitted-data-"
             "fluctuations'，当出现数据波动位于范围内时不触发。建议设置为倍数关系。"}}}}}}}}}};

nlohmann::ordered_json ConfigManager::m_configJson = defaultConfig;

// 构造函数
ConfigManager::ConfigManager(const std::string& configFileName) :
        configPath(std::filesystem::current_path() / "config" / configFileName) {}

// 加载配置文件
void ConfigManager::loadConfig() {
    if (std::filesystem::exists(configPath)) {
        try {
            std::ifstream configFile(configPath);
            if (configFile.peek() == std::ifstream::traits_type::eof()) {
                // 文件为空，恢复默认配置
                OUTPUT_ERRR << "配置文件为空，恢复为默认配置..." << std::endl;
                resetToDefault();
                return;
            }
            configFile >> m_configJson;
            if (!validateConfig()) {
                OUTPUT_ERRR << "配置文件格式不正确，恢复为默认配置..." << std::endl;
                resetToDefault();
            }
        } catch (const std::exception& e) {
            OUTPUT_ERRR << "读取配置文件时发生错误: " << e.what() << std::endl;
            resetToDefault();
        }
    } else {
        OUTPUT_ERRR << "配置文件不存在，生成默认配置...\n";
        resetToDefault();
    }
}

// 保存配置文件
void ConfigManager::saveConfig() const {
    try {
        std::filesystem::create_directories(configPath.parent_path());
        std::ofstream configFile(configPath);
        configFile << m_configJson.dump(4);
        OUPUT_INFO << "配置文件已保存到: " << configPath << std::endl;
    } catch (const std::exception& e) {
        OUTPUT_ERRR << "保存配置文件时发生错误: " << e.what() << std::endl;
    }
}

// 验证配置文件内容
bool ConfigManager::validateConfig() const {
    try {
        if (!m_configJson.contains("appName") || !m_configJson["appName"].is_string())
            return false;
        if (!m_configJson.contains("version") || !m_configJson["version"].is_string())
            return false;
        if (!m_configJson.contains("debug") || !m_configJson["debug"].is_boolean())
            return false;
        if (!m_configJson.contains("deviceLists") || !m_configJson["deviceLists"].is_object())
            return false;
    } catch (...) {
        return false;
    }
    return true;
}

// 重置为默认配置
void ConfigManager::resetToDefault() {
    m_configJson = defaultConfig;
    saveConfig();
}

// 解析路径
std::vector<std::string> ConfigManager::splitPath(const std::string& path) {
    std::vector<std::string> result;
    size_t i = 0;

    while (i < path.length()) {
        // 检测数组访问模式
        if (path[i] == '[') {
            size_t endBracket = path.find(']', i);
            if (endBracket == std::string::npos)
                throw std::invalid_argument("Invalid path syntax");
            result.emplace_back(path.substr(i, endBracket - i + 1));  // 包含 []
            i = endBracket + 1;
        } else if (path[i] == '.') {
            ++i;  // 跳过点分隔符
        } else {
            size_t next = path.find_first_of(".[", i);
            result.emplace_back(path.substr(i, next - i));
            i = next;
        }
    }

    return result;
}

// 获取完整配置
const nlohmann::ordered_json& ConfigManager::getConfig() const {
    return m_configJson;
}

void ConfigStruct::read_config(const nlohmann::json& __config) {
    // IO 控制
    {
        m_IO_controller_config.m_isopen = ConfigManager::getSafe<bool>("deviceLists.IO-controller.isopen", true);
        m_IO_controller_config.Yx[0] =
            ConfigManager::getSafe<std::string>("deviceLists.IO-controller.func_index.Y1.dev_name", "auto-cooling");
        m_IO_controller_config.m_Yx_isOpen[0] =
            ConfigManager::getSafe<bool>("deviceLists.IO-controller.func_index.Y1.isopen", true);
        m_IO_controller_config.Yx[1] =
            ConfigManager::getSafe<std::string>("deviceLists.IO-controller.func_index.Y2.dev_name", "default");
        m_IO_controller_config.m_Yx_isOpen[1] =
            ConfigManager::getSafe<bool>("deviceLists.IO-controller.func_index.Y2.isopen", false);
        m_IO_controller_config.Yx[2] =
            ConfigManager::getSafe<std::string>("deviceLists.IO-controller.func_index.Y3.dev_name", "default");
        m_IO_controller_config.m_Yx_isOpen[2] =
            ConfigManager::getSafe<bool>("deviceLists.IO-controller.func_index.Y3.isopen", false);
        m_IO_controller_config.Yx[3] =
            ConfigManager::getSafe<std::string>("deviceLists.IO-controller.func_index.Y4.dev_name", "default");
        m_IO_controller_config.m_Yx_isOpen[3] =
            ConfigManager::getSafe<bool>("deviceLists.IO-controller.func_index.Y4.isopen", false);
    }
    // 温度模块
    {
        m_temperature_config.m_isopen = ConfigManager::getSafe<bool>("deviceLists.temperature-reader.isopen", true);
        if (ConfigManager::getSafe<std::string>(
                "deviceLists.temperature-reader.auto-cooling.control_mode", "auto-control") == "auto-control") {
            m_temperature_config.m_control_mode = temperature_config::AUTO_CONTROL;
            m_temperature_config.m_description = ConfigManager::getSafe<std::string>(
                "deviceLists.temperature-reader.auto-cooling.auto-control.description", "");
            m_temperature_config.m_temperature_Threshold_open = ConfigManager::getSafe<float>(
                "deviceLists.temperature-reader.auto-cooling.auto-control.temperature-Threshold-open", 40.0);
            m_temperature_config.m_temperature_Threshold_close = ConfigManager::getSafe<float>(
                "deviceLists.temperature-reader.auto-cooling.auto-control.temperature-Threshold-close", 30.0);
            m_temperature_config.m_open_to_output_state = ConfigManager::getSafe<bool>(
                "deviceLists.temperature-reader.auto-cooling.auto-control.open_to_output_state", true);
            if (ConfigManager::getSafe<std::string>(
                    "deviceLists.temperature-reader.auto-cooling.auto-control.bind_controller_func_index", "Y1") ==
                "Y1") {
                m_temperature_config.m_bind_controller_func_index = IO_controller_config::Y1;
            } else if (
                ConfigManager::getSafe<std::string>(
                    "deviceLists.temperature-reader.auto-cooling.auto-control.bind_controller_func_index", "Y1") ==
                "Y2") {
                {
                    m_temperature_config.m_bind_controller_func_index = IO_controller_config::Y2;
                }
            } else if (
                ConfigManager::getSafe<std::string>(
                    "deviceLists.temperature-reader.auto-cooling.auto-control.bind_controller_func_index", "Y1") ==
                "Y3") {
                {
                    m_temperature_config.m_bind_controller_func_index = IO_controller_config::Y3;
                }
            } else if (
                ConfigManager::getSafe<std::string>(
                    "deviceLists.temperature-reader.auto-cooling.auto-control.bind_controller_func_index", "Y1") ==
                "Y4") {
                {
                    m_temperature_config.m_bind_controller_func_index = IO_controller_config::Y4;
                }
            }
        } else if (
            ConfigManager::getSafe<std::string>(
                "deviceLists.temperature-reader.auto-cooling.control_mode", "auto-control") == "keep-close") {
            m_temperature_config.m_control_mode = temperature_config::KEEP_COLSE;
            m_temperature_config.m_description = ConfigManager::getSafe<std::string>(
                "deviceLists.temperature-reader.auto-cooling.keep-close.description", "");
            m_temperature_config.m_open_to_output_state = ConfigManager::getSafe<bool>(
                "deviceLists.temperature-reader.auto-cooling.keep-close.open_to_output_state", true);
        } else if (
            ConfigManager::getSafe<std::string>(
                "deviceLists.temperature-reader.auto-cooling.control_mode", "auto-control") == "keep-open") {
            m_temperature_config.m_control_mode = temperature_config::KEEP_OPEN;
            m_temperature_config.m_description = ConfigManager::getSafe<std::string>(
                "deviceLists.temperature-reader.auto-cooling.keep-open.description", "");
            m_temperature_config.m_open_to_output_state = ConfigManager::getSafe<bool>(
                "deviceLists.temperature-reader.auto-cooling.keep-open.open_to_output_state", true);
        }
    }
    // 称重模块
    {
        m_weight_config.m_isopen = ConfigManager::getSafe<bool>("deviceLists.weight-reader.isopen", true);
        m_weight_config.m_record_real_weight_data =
            ConfigManager::getSafe<bool>("deviceLists.weight-reader.record_real_weight_data.isopen", true);
        m_weight_config.m_freq_ms_record =
            ConfigManager::getSafe<uint32_t>("deviceLists.weight-reader.record_real_weight_data.freq_ms", 500);
        if (ConfigManager::getSafe<std::string>(
                "deviceLists.weight-reader.auto_take_pic.m_control_mode", "add-with-pic") == "add-with-pic") {
            m_weight_config.m_control_mode = weight_config::ADD_WITH_PIC;
            m_weight_config.m_auto_take_pic =
                ConfigManager::getSafe<bool>("deviceLists.weight-reader.auto_take_pic.add-with-pic.isopen", true);
            m_weight_config.m_min_add_step_weight = ConfigManager::getSafe<float>(
                "deviceLists.weight-reader.auto_take_pic.add-with-pic.min-add-step-weight", 50.0);
            m_weight_config.m_permitted_data_fluctuations = ConfigManager::getSafe<float>(
                "deviceLists.weight-reader.auto_take_pic.add-with-pic.permitted-data-fluctuations", 10.0);
            m_weight_config.m_description = ConfigManager::getSafe<std::string>(
                "deviceLists.weight-reader.auto_take_pic.add-with-pic.description", "");
            m_weight_config.m_over_permit_wait_period = ConfigManager::getSafe<int>(
                "deviceLists.weight-reader.auto_take_pic.add-with-pic.over-permit-wait-period", 50);
        }
    }
}